package com.foreverwin.jzymes.production.fqc.service.impl;

import com.foreverwin.jzymes.common.constant.Constants;
import com.foreverwin.jzymes.common.domain.NcData;
import com.foreverwin.jzymes.common.enums.DispositionEnum;
import com.foreverwin.jzymes.common.mapper.NcDataMapper;
import com.foreverwin.jzymes.common.service.*;
import com.foreverwin.jzymes.common.util.BOHandleUtil;
import com.foreverwin.jzymes.common.util.CommonMethods;
import com.foreverwin.jzymes.framework.exception.BusinessException;
import com.foreverwin.jzymes.framework.util.I18nUtil;
import com.foreverwin.jzymes.production.fqc.domain.FqcCheck;
import com.foreverwin.jzymes.production.fqc.domain.FqcCheckBox;
import com.foreverwin.jzymes.production.fqc.domain.FqcCheckNc;
import com.foreverwin.jzymes.production.fqc.enums.CheckResultEnum;
import com.foreverwin.jzymes.production.fqc.mapper.FqcCheckBoxAdviceMapper;
import com.foreverwin.jzymes.production.fqc.mapper.FqcCheckBoxMapper;
import com.foreverwin.jzymes.production.fqc.mapper.FqcCheckMapper;
import com.foreverwin.jzymes.production.fqc.mapper.FqcCheckNcMapper;
import com.foreverwin.jzymes.production.fqc.service.IFqcAdviceService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class FqcAdviceServiceImpl implements IFqcAdviceService {
    @Autowired
    ISiteAdviceService siteAdviceService;
    @Autowired
    IItemAdviceService itemAdviceService;
    @Autowired
    IItemGroupAdviceService itemGroupAdviceService;
    @Autowired
    IResourceAdviceService resourceAdviceService;
    @Autowired
    INCCodeAdviceService ncCodeAdviceService;
    @Autowired
    ICommonService commonService;
    @Autowired
    ISystemRuleAdviceService systemRuleAdviceService;
    @Autowired
    NcDataMapper ncDataMapper;
    @Autowired
    FqcCheckMapper fqcCheckMapper;
    @Autowired
    FqcCheckNcMapper fqcCheckNcMapper;
    @Autowired
    FqcCheckBoxMapper fqcCheckBoxMapper;
    @Autowired
    FqcCheckBoxAdviceMapper fqcCheckBoxAdviceMapper;


    /**
     * FQC检验
     *
     * @param fqcCheck
     * @param fqcCheckBoxs
     * @param fqcCheckNcs
     */
    @Transactional( propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
    public void fqcCheck(FqcCheck fqcCheck, List<FqcCheckBox> fqcCheckBoxs, List<FqcCheckNc> fqcCheckNcs ){
        /**检验检查字段*/
        checkFieldsForFqcCheck( fqcCheck );

        /**检查机种*/
        fqcCheck.setMachineType( commonService.findItemGroupByItem( fqcCheck.getSite(), fqcCheck.getItemBo() ) );

        /**检查资源*/
        Map<String,Object> resourceMap = resourceAdviceService.existResource( fqcCheck.getSite(), fqcCheck.getResrce() );
        /**获取FQC工序*/
        String operation = resourceAdviceService.findOperationByResource( resourceMap );

        /**去毛刺工序、设备*/
        String deburOperation = systemRuleAdviceService.existSystemRule( fqcCheck.getSite(), Constants.SYSTEM_RULE_OPERATION_DEBUR );
        String deburResource = commonService.findOperationDefaultResource( fqcCheck.getSite(), deburOperation );
        if( StringUtils.isBlank( deburResource ) ){
            throw BusinessException.build( "common.defaultResourceOnOperationNotExist", new String[]{ deburOperation, deburResource } );
        }

        fqcCheck.setCreatedDateTime( new Date() );
        fqcCheck.setCreateUserBo( CommonMethods.getUserBo() );
        fqcCheck.setHandle( BOHandleUtil.buildFqcCheckHandle() );

        /**保存不良明细*/
        //List<String> ncCodeList = new ArrayList<>();
        for( FqcCheckNc fqcCheckNc : fqcCheckNcs ){
            /*if( ncCodeList.contains( fqcCheckNc.getNcCode() ) ){
                throw BusinessException.build( "production.fqc.ncCodeDuplicate", new String[]{ fqcCheckNc.getNcCode() } );
            }
            ncCodeList.add( fqcCheckNc.getNcCode() );*/
            ncCodeAdviceService.existNCCode( fqcCheck.getSite(), fqcCheckNc.getNcCode() );
            saveNcData( fqcCheck, fqcCheckNc, deburOperation, deburResource );
        }

        /**检验结果允收，按批量过站*/
        if( CheckResultEnum.ACCEPT.getValue().equals( fqcCheck.getCheckResult() ) ){
            String itemBo = commonService.findSfcItemByItem( fqcCheck.getSite(), fqcCheck.getItemBo() );
            commonService.sfcPassByQty( fqcCheck.getSite(), itemBo, null, null, fqcCheck.getResrce(), operation, fqcCheck.getLotQty(), fqcCheck.getCreatedDateTime()  );
        }

        /**保存检验记录*/
        fqcCheckMapper.insertFqcCheck( fqcCheck );
        for( FqcCheckBox fqcCheckBox : fqcCheckBoxs ){

            /**检查箱号是否已允收*/
            checkFqcCheckBox( fqcCheck.getSite(), fqcCheckBox.getContainerNumber() );

            fqcCheckBox.setFqcCheckBo( fqcCheck.getHandle() );
            fqcCheckBox.setHandle( BOHandleUtil.buildFqcCheckBoxHandle() );
            fqcCheckBoxMapper.insertFqcCheckBox( fqcCheckBox );
        }
        for( FqcCheckNc fqcCheckNc : fqcCheckNcs ){
            fqcCheckNc.setFqcCheckBo( fqcCheck.getHandle() );
            fqcCheckNc.setHandle( BOHandleUtil.buildFqcCheckNcHandle() );
            fqcCheckNcMapper.insertFqcCheckNc( fqcCheckNc );
        }
    }

    /**
     * 保存不良数据
     *
     * @param fqcCheck
     * @param fqcCheckNc
     * @param deburOperation
     * @param deburResource
     */
    public void saveNcData( FqcCheck fqcCheck, FqcCheckNc fqcCheckNc, String deburOperation, String deburResource ){
        NcData ncData = new NcData();
        ncData.setSite( fqcCheck.getSite() );
        ncData.setMachineType( itemGroupAdviceService.findItemGroupBySite( fqcCheck.getSite() ) );
        ncData.setResrce( deburResource );
        ncData.setOperation( deburOperation );
        ncData.setItemBo( commonService.findSfcItemByItem( fqcCheck.getSite(), fqcCheck.getItemBo() ) );
        ncData.setCnc( fqcCheckNc.getCnc() );
        ncData.setNcCode( fqcCheckNc.getNcCode() );
        ncData.setCreatedDateTime( fqcCheck.getCreatedDateTime() );
        ncData.setCreateUserBo( CommonMethods.getUserBo() );

        /**报废*/
        if( fqcCheckNc.getScrapQty() != null && fqcCheckNc.getScrapQty() > 0 ){
            ncData.setNcQty( fqcCheckNc.getScrapQty() );
            ncData.setDisposition( DispositionEnum.SCRAP.getValue() );
            commonService.saveNcData( ncData, false );
        }

        /**返工*/
        if( fqcCheckNc.getReworkQty() != null && fqcCheckNc.getReworkQty() > 0 ){
            ncData.setNcQty( fqcCheckNc.getReworkQty() );
            ncData.setIsRework( "true" );
            ncData.setDisposition( DispositionEnum.OK.getValue() );
            ncData.setHandle( BOHandleUtil.buildNCDataHandle() );
            ncDataMapper.insertNcData( ncData );
        }
    }

    /**
     * 检查箱号是否已允收
     *
     * @param site
     * @param containerNumber
     */
    public void checkFqcCheckBox( String site, String containerNumber ){
        List<FqcCheck> fqcCheckList = fqcCheckBoxAdviceMapper.selectFqcCheckListByBox( site, containerNumber );
        for( FqcCheck fqcCheck : fqcCheckList ){
            if( "A".equals( fqcCheck.getCheckResult() ) ){
                throw BusinessException.build( "production.fqc.containerNumberAlreadyAccept", new String[]{ containerNumber } );
            }
        }
    }

    /**
     * 检查检验字段
     *
     * @param fqcCheck
     */
    public void checkFieldsForFqcCheck( FqcCheck fqcCheck ){
        /**检查站点*/
        siteAdviceService.existSite( fqcCheck.getSite() );
        /**检查物料*/
        itemAdviceService.existItem( fqcCheck.getItemBo() );
        /**检查批量*/
        Assert.isTrue( fqcCheck.getLotQty() != null && fqcCheck.getLotQty() > 0, I18nUtil.getI18nText( "production.fqc.lotQtyNotValid", new Object[]{ fqcCheck.getLotQty() } ) );
        /**检查抽检总数*/
        Assert.isTrue( fqcCheck.getCheckQty() != null && fqcCheck.getCheckQty() > 0, I18nUtil.getI18nText( "production.fqc.checkQtyNotValid", new Object[]{ fqcCheck.getCheckQty() } ) );
        /**检查抽检总数是否超过批量*/
        Assert.isTrue( fqcCheck.getCheckQty() <= fqcCheck.getLotQty(), I18nUtil.getI18nText( "production.fqc.checkQtyExceedLotQty", new Object[]{ fqcCheck.getCheckQty(), fqcCheck.getLotQty() } ) );
        /**检查抽检不良数*/
        Assert.isTrue( fqcCheck.getNcQty() == null || ( fqcCheck.getNcQty() <= fqcCheck.getCheckQty() ), I18nUtil.getI18nText( "production.fqc.ncQtyNotValid", new Object[]{ fqcCheck.getNcQty() } ) );
        /**检查检验判定结果*/
        Assert.hasText( fqcCheck.getCheckResult(), I18nUtil.getI18nText( "production.fqc.checkResultNotBlank" ) );
    }

}
